package com.xinxing.city.recoverycheck.serialport;

import android.content.Context;
import android.util.Log;


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jsjnx.serial.SerialPortManager;
import com.jsjnx.serial.listener.OnOpenSerialPortListener;
import com.xinxing.city.recoverycheck.entitys.KernelAction;
import com.xinxing.city.recoverycheck.entitys.KernelActions;
import com.xinxing.city.recoverycheck.entitys.WeightUp;
import com.xinxing.city.recoverycheck.interfaces.ICallBackCleanState;
import com.xinxing.city.recoverycheck.interfaces.IDecode;
import com.xinxing.city.recoverycheck.interfaces.IDeviceKernel;
import com.xinxing.city.recoverycheck.interfaces.ISerialSendReceiveData;
import com.xinxing.city.recoverycheck.sdk_ttys.AcPackage;
import com.xinxing.city.recoverycheck.sdk_ttys.DecodeAcParser;
import com.xinxing.city.recoverycheck.sdk_ttys.Hexs;
import com.xinxing.city.recoverycheck.sdk_ttys.OrderState;
import com.xinxing.city.recoverycheck.sdk_ttys.ZtlTools;
import com.xinxing.city.recoverycheck.util.LogUtil;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Serialzhi implements ISerialSendReceiveData {
    static SerialPortManager serialPortManager3 = null;

    static boolean open = false;

    private ICallBackCleanState callBackCleanState;
    private static int state = 0;
    private static int zipstate = 0;
    public Context context;
    public static IDecode iDecode;
    private IDeviceKernel kernel2;

    @Override
    public void start(String sPort, int iBaudRate, IDeviceKernel kernel) {
        context = kernel.getContent();
        kernel2 = kernel;
        if (sPort == null || sPort.length() < 5) {
            sPort = "/dev/ttyS3";// 垃圾箱串口
        }

        String DeviceVersion = ZtlTools.getDeviceMdeo();
        if (DeviceVersion.contains("3399")) {
            if (sPort.contains("ttyS3")) {
                sPort = "/dev/ttysWK0";
            }
            if (sPort.contains("ttyS1")) { // 读卡器串口
                sPort = "/dev/ttysWK2";
            }
        }


        int point2 = 9600;
        if (iBaudRate > 0) {
            point2 = iBaudRate;
        }
        int ps = 3;//默认使用3
        if (sPort.contains("ttyS1") || sPort.contains("ttysWK2")
            // || ttyS.equals("ttyS2")
        ) {
            ps = 1;
        }

        serialPortManager3 = new SerialPortManager(sPort, point2, SerialPortManager.SPLICING);

        serialPortManager3.setOnOpenSerialPortListener(new OnOpenSerialPortListener() {
                    @Override
                    public void onSuccess(File device) {
                        open = true;
                        System.out.println("【串口】：打开成功：0 ， ttyS：" + device.getAbsolutePath());
                    }

                    @Override
                    public void onFail(File device, Status status) {
                        open = false;
//                        CC.latest_received_ac_data_time = 1;
                        System.out.println("【串口】：打开失败：0 ， latest_received_ac_data_time：");
                    }
                })
                .setOnSerialPortDataListener(buffer -> {

                    if (buffer == null || buffer.length < 1) {
                        System.out.println("【收到串口1数据】：报文长度错误：0 ， ");
                        return;
                    }
                    iDecode = new IDecode() {
                        @Override
                        public void iDecode(byte[] buffer) {
                            read_package(buffer);
                        }
                    };
                    String recvPackeHex = Hexs.ByteToHex(buffer);
                    DecodeAcParser.unboxing(buffer, recvPackeHex);


                }).start();

    }

    public void read_package(byte[] buffer) {
//        Log.e("xiaozhi", "【AC报文】读:"
//                + "0x" + Hexs.ByteToHex(new byte[]{buffer[21]})
//                + " hex:" + Hexs.ByteToHex(buffer));

//        System.out.println("【AC报文】读:"
//                + "0x" + Hexs.ByteToHex(new byte[]{buffer[21]})
//                + " hex:" + Hexs.ByteToHex(buffer)
//        );
        if (!AcPackage.isPack(buffer)) {
            Log.e("xiaozhi", "【AC报文】 错误");
            if (Hexs.ByteToHex(new byte[]{buffer[21]}).equals("04")) {
                return;
            }

        }

        Log.e("xiaozhi", "【AC报文】读:"
                + "0x" + Hexs.ByteToHex(new byte[]{buffer[21]})
                + " hex:" + Hexs.ByteToHex(buffer));
        LogUtil.sendLog("【AC报文】读:"
                + "0x" + Hexs.ByteToHex(new byte[]{buffer[21]})
                + " hex:" + Hexs.ByteToHex(buffer));
        int size = buffer.length;
        if (buffer[size - 1] != (byte) 0x0a) {
            return;
        }
        List<String> params = new ArrayList<>();
        switch (buffer[21]) {
            case (byte) 0x04://设备状态应答
                byte[] bytes2 = Hexs.subArrayUsingSystemArraycopy(buffer, 26, size);
                String s04 = Hexs.ByteToHex(bytes2);
                byte[] byteArray2 = hexStringToByteArray2(s04);
                String jsonString2 = new String(byteArray2, StandardCharsets.UTF_8);
                params.add(jsonString2);
                EventBus.getDefault().post(new KernelAction(KernelActions.R_16_HEART, params));
                String jsn = params.get(0);
                Gson gson = new Gson();
                Type dev = new TypeToken<List<WeightUp>>() {
                }.getType();

                List<WeightUp> weightUps = gson.fromJson(jsn, dev);

                if (callBackCleanState != null) {
                    callBackCleanState.setState(weightUps.get(0).getCleanDoorState());
                    callBackCleanState = null;
                }
                break;
            case (byte) 0x06://投递开门命令应答
                state = OrderState.openDoor;
                params.add(String.valueOf((int) buffer[27]));
                params.add(String.valueOf((int) buffer[28]));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_06_OPNEDOOR, params));
                break;
            case (byte) 0x07://投递重量上传
                long weightotal = bytesToInt2(new byte[]{buffer[46], buffer[45], buffer[44], buffer[43]});
                long alltotal = bytesToInt2(new byte[]{buffer[50], buffer[49], buffer[48], buffer[47]});

                params.add(String.valueOf(weightotal));
                params.add(String.valueOf(alltotal));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_07_WEIGHT, params));
                if (state == OrderState.closeDoor) {
                    reply07();
                }
                break;
            case (byte) 0x16:

                byte[] bytes = Hexs.subArrayUsingSystemArraycopy(buffer, 26, size);
                String s16 = Hexs.ByteToHex(bytes);
                byte[] byteArray = hexStringToByteArray2(s16);
                String jsonString = new String(byteArray, StandardCharsets.UTF_8);
                List<String> params2 = new ArrayList<>();
                params2.add(jsonString);
                EventBus.getDefault().post(new KernelAction(KernelActions.R_16_HEART, params2));
//                Gson gson2 = new Gson();
//                Type dev2 = new TypeToken<List<WeightUp>>() {
//                }.getType();
//                List<WeightUp> weightUps2 = gson2.fromJson(jsonString, dev2);
//                for (WeightUp weightUp : weightUps2) {
//                    if (weightUp.getDoorid() == 1) {
//                        int zipCount2 = (int) SharedPreferencesUtils.getParam(context, "zip_count", 0);
//                        Log.e("【AC报文】", "zipstate " + zipstate + " getDeliveryDoorState " + weightUp.getDeliveryDoorState() + " getCleanDoorState  " +
//                                weightUp.getCleanDoorState() + "  zipCount2 " + zipCount2 + "  getSpillRed " + weightUp.getSpillRed());
//                        if (zipstate == 0 && weightUp.getDeliveryDoorState() == 0 && weightUp.getCleanDoorState() == 0 && zipCount2 < 5 && weightUp.getSpillRed() == 1) {
//                            Log.e("【AC报文】", "开启压缩");
//                            kernel2.getTTS().speak("正在压缩，请勿靠近");
//                            openZip(1);
//                        }
//                        params.add(String.valueOf(weightUp.getSpillRed()));
//                        EventBus.getDefault().post(new KernelAction(KernelActions.R_23_OVER, params));
//                    }
//
//                }
                break;
            case (byte) 0x0a://投递门关门命令回复
                if ((int) buffer[27] == 1) {
                    params.add(Hexs.ByteToHex(buffer));
                    EventBus.getDefault().post(new KernelAction(KernelActions.R_0A_COLSE, params));

                }
                break;

            case (byte) 0x0d:
                rep0E();
                break;
            case (byte) 0x0c://发送清运开门命令回复
                if ((int) buffer[27] == 1) {
//                    SharedPreferencesUtils.setParam(context, "zip_count", 0);
                }
                break;
            case (byte) 0x21://重量传感器(称重实时数据) 单位：克
                long weightotal2 = bytesToInt2(new byte[]{buffer[46], buffer[45], buffer[44], buffer[43]});
                long alltotal2 = bytesToInt2(new byte[]{buffer[50], buffer[49], buffer[48], buffer[47]});
                List<String> params3 = new ArrayList<>();
                params3.add(String.valueOf(weightotal2));
                params3.add(String.valueOf(alltotal2));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_21_WEIGHT, params3));
                break;
            case (byte) 0x23://满溢(红外) 单位:是/否
                params.add(String.valueOf((int) buffer[27]));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_23_OVER, params));
                break;
            case (byte) 0x26://投递门状态
                Log.e("xiaozhi", "投递门状态");
                params.add(Hexs.ByteToHex(buffer));
                params.add(String.valueOf((int) buffer[27]));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_26_DOOR, params));
                break;
            case (byte) 0x27://清运门状态
                params.add(Hexs.ByteToHex(buffer));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_CLEAN_DOOR, params));
                break;
            case (byte) 0x42://压缩状态上报
                zipstate = (int) buffer[28];
                Log.e("xiaozhi", "0x42 " + zipstate);
                params.add(String.valueOf((int) buffer[28]));
                EventBus.getDefault().post(new KernelAction(KernelActions.R_42_ZIP, params));
                break;

            case (byte) 0x41://
                Log.e("xiaozhi", "收到压缩指令 ");

                break;

        }

    }

    @Override
    public void stop() {
        serialPortManager3.closeSerialPort();
    }

    @Override
    public void openDoor(int doornum) {
        AcPackage p2 = new AcPackage();

        System.out.println("编码后的HEX格式：" + AcPackage.isPack(p2.getPackage()));

        byte ACdoorId = 1;
        String orderid = "964b71d3a305d7d97116783592470002";
        p2.frame = 0x05;
        p2.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(orderid));

        byte[] _package = p2.getPackage();
        send_cmd(_package);
    }

    @Override
    public void closeDoor(int doornum) {
        byte ACdoorId = 1;

        AcPackage p = new AcPackage();
        p.frame = 0x09;
        p.body = Hexs.byteMerger(new byte[]{(byte) ACdoorId});
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);
    }

    @Override
    public void getWeight(int doornum) {

        AcPackage p2 = new AcPackage();
        System.out.println("编码后的HEX格式：" + AcPackage.isPack(p2.getPackage()));
        p2.frame = 0x03;
        p2.body = Hexs.byteMerger(new byte[]{});

        byte[] _package = p2.getPackage();
        send_cmd(_package);
    }


    @Override
    public void openZip(int doornum) {
        byte ACdoorId = 1;
        String other = "01010005000000";
        AcPackage p = new AcPackage();
        p.frame = 0x40;
        p.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(other));
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);

    }
    public void zipState(){
        byte ACdoorId = 1;
        String other = "00010005000000";
        AcPackage p = new AcPackage();
        p.frame = 0x40;
        p.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(other));
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);
    }
    public void rep0E(){
        AcPackage p2 = new AcPackage();

        System.out.println("编码后的HEX格式：" + AcPackage.isPack(p2.getPackage()));

        byte ACdoorId = 1;
        String orderid = "964b71d3a305d7d97116783592470002";
        p2.frame = 0x0e;
        p2.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(orderid));

        byte[] _package = p2.getPackage();
        send_cmd(_package);
    }
    @Override
    public void closeZip(int doornum) {
        byte ACdoorId = 1;
        String other = "01020005000000";
        AcPackage p = new AcPackage();
        p.frame = 0x40;
        p.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(other));
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);
    }

    @Override
    public void openLock(int doornum) {
        AcPackage p2 = new AcPackage();
        System.out.println("编码后的HEX格式：" + AcPackage.isPack(p2.getPackage()));
        byte ACdoorId = 1;
        String orderid = "964b71d3a305d7d97116783592470002";
        p2.frame = 0x0B;
        p2.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(orderid));
        byte[] _package = p2.getPackage();
        send_cmd(_package);
    }

    @Override
    public void getState() {

    }

    public void getClearState(ICallBackCleanState iCallBackCleanState) {
        callBackCleanState = iCallBackCleanState;
        AcPackage p2 = new AcPackage();
        System.out.println("编码后的HEX格式：" + AcPackage.isPack(p2.getPackage()));
        p2.frame = 0x03;
        p2.body = Hexs.byteMerger(new byte[]{});

        byte[] _package = p2.getPackage();
        send_cmd(_package);
    }


    @Override
    public void sendSingleRfid() {

    }

    @Override
    public void sendLoopRfid() {

    }

    @Override
    public void fault() {

    }

    @Override
    public void deviceState() {

    }


    @Override
    public void reply07() {
        byte ACdoorId = 1;
        String orderid = "964b71d3a305d7d97116783592470002";
        AcPackage p = new AcPackage();
        p.frame = 0x08;

        p.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(orderid));
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);
    }

    @Override
    public void reply0d() {
        byte ACdoorId = 1;
        String orderid = "964b71d3a305d7d97116783592470002";
        AcPackage p = new AcPackage();
        p.frame = 0x0e;

        p.body = Hexs.byteMerger(new byte[]{ACdoorId}, Hexs.HexTobyte(orderid));
        byte[] _package = p.getPackage();
        String hex = Hexs.ByteToHex(_package);

        System.out.println("编码后的HEX格式：" + hex);

        send_cmd(_package);
    }

    @Override
    public boolean sendConfig(String str) {
        Log.e("TT",str);
        AcPackage p2 = new AcPackage();
        p2.frame= 0x17;
        p2.body = Hexs.byteMerger( Hexs.HexTobyte(str));
        byte[] _package = p2.getPackage();
        boolean b = send_cmd(_package);
        return b;
    }

    public static boolean send_cmd(byte[] buffer) {
        byte[] bOutArray = (byte[]) buffer;

        if (bOutArray != null) {
            if (serialPortManager3 != null) {
                String hexId = Hexs.ByteToHex(bOutArray);


                boolean wrt = serialPortManager3.sendBytes(bOutArray);
                LogUtil.sendLog("【AC报文】写:"
                        + "0x" + Hexs.ByteToHex(new byte[]{bOutArray[21]})
                        + serialPortManager3.getName() + " hex:" + hexId
                        + " sendBytes:" + wrt);
                System.out.println("【AC报文】写:"
                        + "0x" + Hexs.ByteToHex(new byte[]{bOutArray[21]})
                        + serialPortManager3.getName() + " hex:" + hexId
                        + " sendBytes:" + wrt
                );
                return wrt;

            }
        }
        return false;
    }

    public static byte[] hexStringToByteArray2(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }

    @Override
    public void getWeightReset(int doornum) {

    }

    @Override
    public void getWeightCorrect1(int doornum) {

    }

    @Override
    public void getWeightCorrect2(int doornum) {

    }

    @Override
    public void openCut(int doornum) {

    }

    @Override
    public void closeCut(int doornum) {

    }

    public static int bytesToInt2(byte[] bs) {

        int signedInt = ByteBuffer.wrap(bs).getInt();
        return signedInt;
    }

    public static List<byte[]> splitByteArray(byte[] original, int packetSize) {
        List<byte[]> packets = new ArrayList<>();
        for (int i = 0; i < original.length; i += packetSize) {
            int endIndex = Math.min(i + packetSize, original.length);
            byte[] packet = Arrays.copyOfRange(original, i, endIndex);
            packets.add(packet);
        }
        return packets;
    }
}
